package org.embedchat.protocol.message.server;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import org.embedchat.protocol.message.AbstractMessage;

/**
 * Room list message format: 
 * 	commandId - short
 * 	bodyLength - uint
 * 	usersCount - uint
 * than loop for users:
 * 	userId = uint;
 * 	userName = utf;
 * 
 * @author koba
 *
 */

public class UsersListMessage extends AbstractMessage {

	private static final long serialVersionUID = 1661782047651426076L;
	private List<UserDescription> users = new ArrayList<UserDescription>();
	
	public List<UserDescription> getUsers() {
		return users;
	}

	public void addUser(int userId, String userName) {
		users.add(new UserDescription(userId, userName));
	}

	public int getUsersCount() {
		return users.size();
	}
	
	@Override
	public int getMessageBodyLength() {
		int length = 2;
		for (UserDescription desc : users) {
			length += desc.getDescriptionMessageLength();
		}
		return length;
	}
	
	@Override
	public String toString() {
		return new ToStringBuilder(this).append("users", users).toString();
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof UsersListMessage)) {
			return false;
		}
		UsersListMessage castOther = (UsersListMessage) other;
		Collections.sort(users);
		Collections.sort(castOther.users);
		return new EqualsBuilder().append(users, castOther.users).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(users).toHashCode();
	}

	public class UserDescription implements Comparable {
		
		private int userId;
		private String userName;
		
		@Override
		public String toString() {
			return new ToStringBuilder(this).append("userId", userId).append(
					"userName", userName).toString();
		}

		@Override
		public boolean equals(final Object other) {
			if (!(other instanceof UserDescription))
				return false;
			UserDescription castOther = (UserDescription) other;
			return new EqualsBuilder()
				.append(userId, castOther.userId)
				.append(userName, castOther.userName)
				.isEquals();
		}

		@Override
		public int hashCode() {
			return new HashCodeBuilder().append(userId).append(userName)
					.toHashCode();
		}

		public UserDescription(int userId, String userName) {
			this.userId = userId;
			this.userName = userName;
		}

		public int getUserId() {
			return userId;
		}

		public void setUserId(int userId) {
			this.userId = userId;
		}

		public String getUserName() {
			return userName;
		}

		public void setUserName(String userName) {
			this.userName = userName;
		}
		
		public int getDescriptionMessageLength() {
			return 2 + userName.getBytes().length;
		}

		public int compareTo(Object object) {
			if (object == null) {
				return -1;
			}
			UserDescription compareTo;
			if (object instanceof UserDescription) {
				compareTo = (UserDescription) object;
				if (compareTo.getUserId() > userId) {
					return 1;
				}
				if (compareTo.getUserId() == userId) {
					return 0;
				}
			}
			return -1;
		}
	}
}
